﻿using System;
using System.Collections.Generic;
using System.Text;
using TSVNAddin.TSVN;
using TSVNAddin.SVN;
using TSVNAddin.Config;
using EnvDTE80;

namespace TSVNAddin.Core
{
	public class CommandFactory
	{
		public virtual CommandDictionary CreateCommands(DTE2 applicationObject, IDialogFactory dialogFactory)
		{
			SolutionAdapter dteAdapter = new SolutionAdapter(applicationObject);

			var configStorage = new ConfigStorage(new XmlFileStorage());
			TortoiseProcExecutor tExecutor = new TortoiseProcExecutor(new ProcessStarter(), configStorage);
			WorkingContext workingContext = new WorkingContext(dteAdapter, new SVNClientAdapter());

			CommandDictionary commands = new CommandDictionary();

			var activeCommandContext = new ActiveCommandContext(new ActiveDocumentAdapter(applicationObject), workingContext);
			commands.Add(CommandType.ActiveDiff, new TortoisePathCommand(tExecutor, activeCommandContext, TortoiseProcCommandType.Diff));

			var rootCommandContext = new RootCommandContext(workingContext);
			commands.Add(CommandType.RootUpdate, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Update));
			commands.Add(CommandType.RootCommit, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Commit));
			commands.Add(CommandType.RootShowLog, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Log));
			commands.Add(CommandType.RootRepoBrowser, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Repobrowser));
			commands.Add(CommandType.RootShowChanges, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Repostatus));
			commands.Add(CommandType.RootRevisionGraph, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Revisiongraph));
			commands.Add(CommandType.RootUpdateToRevision, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Update, TortoiseProcArgumentType.rev));
			//commands.Add(CommandType.Rename, new NotImplementedCommand());
			//commands.Add(CommandType.Delete, new NotImplementedCommand());
			commands.Add(CommandType.RootRevert, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Revert));
			commands.Add(CommandType.RootGetLock, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Lock));
			commands.Add(CommandType.RootReleaseLock, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Unlock));
			commands.Add(CommandType.RootBranchTag, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Copy));
			commands.Add(CommandType.RootSwitch, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Switch));
			commands.Add(CommandType.RootMerge, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Merge));
			commands.Add(CommandType.Blame, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Blame));
			commands.Add(CommandType.RootCreatePatch, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.CreatePatch));
			commands.Add(CommandType.RootApplyPatch, new NotImplementedCommand());
			commands.Add(CommandType.RootProperties, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Properties));
			commands.Add(CommandType.SetWorkingRoot, new SetWorkingRootCommand(new WorkingRootRecover(dialogFactory), workingContext));
			commands.Add(CommandType.Settings, new TortoisePathCommand(tExecutor, rootCommandContext, TortoiseProcCommandType.Settings));
			commands.Add(CommandType.DiskBrowser, new NotImplementedCommand());
			commands.Add(CommandType.Checkout, new CheckoutCommand(tExecutor, workingContext));
			commands.Add(CommandType.CreateReposiotry, new CreateRepositoryCommand(tExecutor, new FolderBrowserDialogAdapter()));
			commands.Add(CommandType.AboutTortoiseSVNAddin, new AboutAddinCommand(dialogFactory, configStorage));
			commands.Add(CommandType.AboutTortoiseSVN, new AboutTortoiseSVNCommand(tExecutor));

			var selectedItems = new SelectedItemsAdapter(applicationObject);
			var singleItemCommandContext = new ItemCommandContext(selectedItems, workingContext, new SingleItemCompatibility());
			var multiItemCommandContext = new ItemCommandContext(selectedItems, workingContext, new MultiItemCompatibility());

			commands.Add(CommandType.ItemDiff, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Diff));
			commands.Add(CommandType.ItemUpdate, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Update));
			commands.Add(CommandType.ItemCommit, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Commit));
			commands.Add(CommandType.ItemShowLog, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Log));
			commands.Add(CommandType.ItemRepoBrowser, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Repobrowser));
			commands.Add(CommandType.ItemShowChanges, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Repostatus));
			commands.Add(CommandType.ItemRevisionGraph, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Revisiongraph));
			commands.Add(CommandType.ItemUpdateToRevision, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Update, TortoiseProcArgumentType.rev));
			//commands.Add(CommandType.ItemRename, new NotImplementedCommand());
			//commands.Add(CommandType.ItemDelete, new NotImplementedCommand());
			commands.Add(CommandType.ItemRevert, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Revert));
			commands.Add(CommandType.ItemGetLock, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Lock));
			commands.Add(CommandType.ItemReleaseLock, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Unlock));
			commands.Add(CommandType.ItemBranchTag, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Copy));
			commands.Add(CommandType.ItemSwitch, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Switch));
			commands.Add(CommandType.ItemMerge, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Merge));
			commands.Add(CommandType.ItemBlame, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.Blame));
			//Delete and add to ignore list
			commands.Add(CommandType.ItemCreatePatch, new TortoisePathCommand(tExecutor, singleItemCommandContext, TortoiseProcCommandType.CreatePatch));
			//commands.Add(CommandType.ItemApplyPatch, new NotImplementedCommand());
			commands.Add(CommandType.ItemProperties, new TortoisePathCommand(tExecutor, multiItemCommandContext, TortoiseProcCommandType.Properties));

			return commands;
		}
	}
}
